package com.github.byakkili.bim.core.protocol.impl.jsonprotobuf.ws;

import com.github.byakkili.bim.core.BimSession;
import com.github.byakkili.bim.core.protocol.CommandFrame;
import com.github.byakkili.bim.core.protocol.impl.json.JsonMsg;
import com.github.byakkili.bim.core.protocol.impl.jsonprotobuf.BaseJsonProtobufCodec;
import com.github.byakkili.bim.core.util.BimSessionUtils;
import com.github.byakkili.bim.core.util.JsonUtils;
import com.github.byakkili.bim.core.util.ProtobufUtils;
import com.google.protobuf.Message;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;

/**
 * @author Guannian Li
 */
@Sharable
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class WsJsonProtobufCodec extends BaseJsonProtobufCodec<TextWebSocketFrame> {
    /**
     * 单例
     */
    public static final WsJsonProtobufCodec INSTANCE = new WsJsonProtobufCodec();

    @Override
    protected void decode(ChannelHandlerContext ctx, TextWebSocketFrame textWsFrame, List<Object> out) {
        BimSession session = BimSessionUtils.get(ctx.channel());
        CommandFrame<Message> commandFrame = decodeToFrame(session, textWsFrame.text());

        if (commandFrame != null) {
            out.add(commandFrame);
        }
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, CommandFrame<Message> frame, List<Object> out) {
        Integer command = frame.getCommand();
        Message msg = frame.getMsg();

        String noCmdJsonStr = ProtobufUtils.serializeJson(msg);

        @SuppressWarnings("unchecked")
        Map<Object, Object> jsonMap = JsonUtils.parse(noCmdJsonStr, Map.class);
        jsonMap.put(JsonMsg.COMMAND_FIELD, command);
        String jsonStr = JsonUtils.stringify(jsonMap);

        TextWebSocketFrame textWsFrame = new TextWebSocketFrame(jsonStr);
        out.add(textWsFrame);
    }
}
